package com.ymt.bpm.web.action.process;

import com.alibaba.fastjson.JSONObject;
import com.ymt.bpm.appboot.BpmpProperties;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.service.engine.task.PiService;
import com.ymt.bpm.service.engine.task.TiService;
import com.ymt.bpm.util.Const;
import com.ymt.bpm.util.AES;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;

/**
 * Created by Johnny on 2017/4/18.
 */
@Controller
@RequestMapping(path="/view/process")
@EnableConfigurationProperties(BpmpProperties.class)
public class ProcessJspController {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private Environment env;

    @Autowired
    private BpmpProperties bpmp;

    @Autowired
    private MDao dao;

    @Autowired
    private PiService ps;

    @Autowired
    private TiService ts;

    private String formCdnPath = null;

    @GetMapping(path="/jspage", produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView tojsp(HttpServletRequest request) {
        String path = request.getParameter("path");
        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String lang = userDetail.get(Const.LANG);
        if (log.isDebugEnabled()) {
            log.debug("tojsp path:"+path);
            log.debug("tojsp lang:"+lang);
        }
        String[] profile = env.getActiveProfiles();
        String productionVersion = env.getProperty("bpmp.production-version", "0");
        String cdn = env.getProperty("bpmp.cdn", "/bpmp-resources");
        ModelAndView view = new ModelAndView("/jsp/"+path+".jsp");

        //redirect other parameters
        Enumeration<String> paramEnu = request.getParameterNames();
        while(paramEnu.hasMoreElements()) {
            String param = paramEnu.nextElement();
            view.addObject(param, request.getParameter(param));
        }

        view.addObject("profile", profile[0]);
        view.addObject("productionVersion", productionVersion);
        view.addObject("cdn", cdn);
        view.addObject("fmdCtx", env.getProperty("fmd.ctx"));
        view.addObject(Const.LANG, lang);

        return view;
    }

    @GetMapping(path="/todo/{tiId}")
    public ModelAndView todo(HttpServletRequest request,
                             @PathVariable("tiId")String id) {
        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String tenantId = userDetail.get(com.ymt.bpm.util.Const.TENANT_ID);
        String loginName = userDetail.get(Const.LOGINNAME);
        String displayName = userDetail.get(Const.DISPLAYNAME);
        String lang = userDetail.get(Const.LANG);
        if (log.isDebugEnabled()) {
            log.debug("todo tenantId:"+tenantId);
            log.debug("todo loginName:"+loginName);
            log.debug("todo tiId encrypt:"+id);
            log.debug("todo form locatoin:"+bpmp.getFormLocation());
        }
        String path = "/jsp/tasks/todo.jsp";
        if ("cdn".equalsIgnoreCase(bpmp.getFormLocation())) {
            path = "engine/tasks/todo";
        }
        ModelAndView view = baseView(request, path);
        view.addObject(Const.LOGINNAME, loginName);
        view.addObject(Const.DISPLAYNAME, displayName);
        view.addObject("formCdnPath", getFormCdnPath(tenantId));
        String contextRealPath = request.getServletContext().getRealPath("/");
        view = ts.getTodoView(tenantId, view, loginName, id, contextRealPath, lang, 0, bpmp.getFormLocation());
        return view;
    }

    @GetMapping(path="/viewpi/{piEid}")
    public ModelAndView viewpi(HttpServletRequest request,
                             @PathVariable("piEid")String piEidEnc,
                             @RequestParam(name="doneTiId", required = false)String doneTiIdEnc) {
        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String tenantId = userDetail.get(com.ymt.bpm.util.Const.TENANT_ID);
        String loginName = userDetail.get(Const.LOGINNAME);
        String displayName = userDetail.get(Const.DISPLAYNAME);
        String lang = userDetail.get(Const.LANG);
        if (log.isDebugEnabled()) {
            log.debug("viewpi tenantId:"+tenantId);
            log.debug("viewpi loginName:"+loginName);
            log.debug("viewpi piEid encrypt:"+piEidEnc);
            log.debug("viewpi doneTiId encrypt:"+doneTiIdEnc);
            log.debug("viewpi form locatoin:"+bpmp.getFormLocation());
        }
        String path = "/jsp/tasks/viewpi.jsp";
        if ("cdn".equalsIgnoreCase(bpmp.getFormLocation())) {
            path = "engine/tasks/viewpi";
        }
        ModelAndView view = baseView(request, path);
        view.addObject(Const.LOGINNAME, loginName);
        view.addObject(Const.DISPLAYNAME, displayName);
        view.addObject("formCdnPath", getFormCdnPath(tenantId));
        String contextRealPath = request.getServletContext().getRealPath("/");
        view = ts.getPiView(tenantId, view, loginName, piEidEnc, doneTiIdEnc, contextRealPath, lang, 0, bpmp.getFormLocation());
        return view;
    }

    @RequestMapping(path="/startpi/key/{bpdId}")
    public ModelAndView startPiByKey(HttpServletRequest request,
                                     @PathVariable("bpdId")String id) {
        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String tenantId = userDetail.get(Const.TENANT_ID);
        String loginName = userDetail.get(Const.LOGINNAME);
        String displayName = userDetail.get(Const.DISPLAYNAME);
        String bpdId = AES.decrypt(id);
        if (log.isDebugEnabled()) {
            log.debug("startPiByKey tenantId:"+tenantId);
            log.debug("startPiByKey loginName:"+loginName);
            log.debug("startPiByKey displayName:"+displayName);
            log.debug("startPiByKey bpdId:"+bpdId);
        }

        //start draft
        JSONObject ret = ps.startDraft(tenantId, loginName, displayName, bpdId);

        //第一个环节不是人工起草环节，跳转到提示页面
        if ("FIRST_NOT_USERTASK".equalsIgnoreCase(ret.getString("msg"))) {
            ModelAndView viewErr = new ModelAndView("/html/error-msg.jsp?msg=FIRST_NOT_USERTASK");
            return viewErr;
        }

        ModelAndView view = new ModelAndView("redirect:/view/process/todo/"+AES.encrypt(ret.getString("tiId")));
        return view;

    }

    /**
     * 用于压力测试的接口，返回json
     * @param request
     * @param id
     * @return
     */
    @RequestMapping(path="/startpijs/key/{bpdId}")
    @ResponseBody
    public JSONObject startPiByKeyJson(HttpServletRequest request,
                                     @PathVariable("bpdId")String id) {
        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String tenantId = userDetail.get(Const.TENANT_ID);
        String loginName = userDetail.get(Const.LOGINNAME);
        String displayName = userDetail.get(Const.DISPLAYNAME);
        String bpdId = AES.decrypt(id);
        if (log.isDebugEnabled()) {
            log.debug("startPiByKey tenantId:"+tenantId);
            log.debug("startPiByKey loginName:"+loginName);
            log.debug("startPiByKey displayName:"+displayName);
            log.debug("startPiByKey bpdId:"+bpdId);
        }

        //start draft
        JSONObject ret = ps.startDraft(tenantId, loginName, displayName, bpdId);

        ret.put("tiIdEnc", AES.encrypt(ret.getString("tiId")));

        return ret;

    }

    @RequestMapping(path="/startpi/tpl/{tiId}")
    public ModelAndView startPiByTpl(HttpServletRequest request,
                                     @PathVariable("tiId")String id) {
        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String tenantId = userDetail.get(Const.TENANT_ID);
        String loginName = userDetail.get(Const.LOGINNAME);
        String tiId = AES.decrypt(id);
        if (log.isDebugEnabled()) {
            log.debug("startPiByTpl tenantId:"+tenantId);
            log.debug("startPiByTpl loginName:"+loginName);
            log.debug("startPiByTpl tiId:"+tiId);
        }
        JSONObject ret = ts.draftFromTpl(tenantId, loginName, tiId);

        if ("401".equals(ret.getString("msg"))) {
            ModelAndView viewErr = new ModelAndView("/html/error-401.jsp");
            return viewErr;
        }

        if (log.isDebugEnabled()) {
            log.debug("startPiByTpl new tiId:"+ret.getString("tiId"));
        }
        ModelAndView view = new ModelAndView("redirect:/view/process/todo/"+AES.encrypt(ret.getString("tiId")));
        return view;
    }

    private ModelAndView baseView(HttpServletRequest request, String path) {
//        String loginName = userDetail.get(Const.LOGINNAME);
//        String displayName = userDetail.get(Const.DISPLAYNAME);
        ModelAndView view = new ModelAndView(path);

        //redirect other parameters
        Enumeration<String> paramEnu = request.getParameterNames();
        while(paramEnu.hasMoreElements()) {
            String param = paramEnu.nextElement();
            view.addObject(param, request.getParameter(param));
        }

        Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String lang = userDetail.get(Const.LANG);
        String[] profile = env.getActiveProfiles();
        String productionVersion = env.getProperty("bpmp.production-version", "0");
        String cdn = env.getProperty("bpmp.cdn", "/bpmp-resources");

        view.addObject("profile", profile[0]);
        view.addObject("productionVersion", productionVersion);
        view.addObject("cdn", cdn);
        view.addObject(Const.LANG, lang);
        view.addObject("fmdCtx", env.getProperty("fmd.ctx"));

        return view;
    }

    private String getFormCdnPath(String tenantId) {
        if (formCdnPath==null) {
            formCdnPath = env.getProperty("oss.form.schema") +
                    env.getProperty("oss.form.bucket-name") + "." +
                    env.getProperty("oss.form.endpoint") + "/forms/";
        }
        String rtn = formCdnPath;
        if (tenantId==null || tenantId.length()==0) {
            rtn += AES.encrypt("0");
        } else {
            rtn += AES.encrypt(tenantId);
        }
        rtn += "/process/inline/";
        return rtn;
    }

}
